package com.sky.controller.admin;

import com.sky.po.ImageEx;
import com.sky.result.Result;
import com.sky.utils.AliOssUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.util.ImageHelper;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.bytedeco.opencv.presets.opencv_core;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@RestController
@RequestMapping("/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {

    @Autowired
    private AliOssUtil aliOssUtil;

    ImageEx imageEx=new ImageEx();

    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file) throws Exception {
        log.info("文件上传{}", file);
        byte[] bytes = file.getBytes();
        String imageName = UUID.randomUUID().toString();
        QiniuCloudUtil qiniuUtil = new QiniuCloudUtil();
        //使用base64方式上传到七牛云
        String imageUrl = qiniuUtil.put64image(bytes, imageName);
        return Result.success(imageUrl);

    }

    @PostMapping("/handle")
    public Result<ImageEx> handle(@RequestBody ImageRequestObject imageUrl) throws IOException {
        QiniuImageLoader qiniuImageLoader=new QiniuImageLoader();
        BufferedImage img=qiniuImageLoader.loadImageFromQiniu(imageUrl.getImageUrl());
        // 语言库位置（修改为跟自己语言库文件夹的路径）
        //String lagnguagePath = "E:\\tessdata";
        String languagePath = this.getClass().getClassLoader().getResource("tessdata").getPath();// 去掉开头的斜线
        if (languagePath.startsWith("/")) {
            languagePath = languagePath.substring(1);
        }

        // 这里对图片黑白处理,增强识别率.这里先通过截图,截取图片中需要识别的部分
        img = ImageHelper.convertImageToGrayscale(img);
        // 图片锐化,自己使用中影响识别率的主要因素是针式打印机字迹不连贯,所以锐化反而降低识别率
        img = ImageHelper.convertImageToBinary(img);
        // 图片放大5倍,增强识别率(很多图片本身无法识别,放大7倍时就可以轻易识,但是考滤到客户电脑配置低,针式打印机打印不连贯的问题,这里就放大7倍)
        img = ImageHelper.getScaledInstance(img, img.getWidth() * 7, img.getHeight() * 7);
        //
        ITesseract instance = new Tesseract();
        //设置训练库的位置
        instance.setDatapath(languagePath);
        //chi_sim ：简体中文， eng    根据需求选择语言库
        instance.setLanguage("chi_sim");
        String result = null;
        long startTime = System.currentTimeMillis();
        try {
            result = instance.doOCR(img);
        } catch (TesseractException e) {
            throw new RuntimeException(e);
        }
        //long endTime = System.currentTimeMillis();
//        System.out.println("Time is：" + (endTime - startTime) + " 毫秒");
//        System.out.println("result: ");
        //System.out.println(result);
        String info = result;
        // 尝试清理和规范化地址部分
        info = info.replace(" , _ ,txA 应", "").trim();
        String[] lines = info.split("\n");
        Map<String, String> companyInfoMap = new HashMap<>();
        for (String line : lines) {
            int colonIndex = line.indexOf(":");
            if (colonIndex != -1) {
                String key = line.substring(0, colonIndex).trim().replace(" ", "");
                String value = line.substring(colonIndex + 1).trim().replace(" ", "");
                // 进一步清理值中的多余字符或换行符等
                value = value.replaceAll("[“”‘’]", "").replaceAll("\\s+", " ").trim();
                companyInfoMap.put(key, value);
            }
        }
        Map<String,String> mapadd=new HashMap<>();
        mapadd= processLinesWithPredefinedKeys(companyInfoMap);

        // 创建一个新的Map来存储合并后的结果
        Map<String, String> mergedMap = new HashMap<>(companyInfoMap);

        // 遍历map2，合并键值
        for (Map.Entry<String, String> entry : mapadd.entrySet()) {
            if (!mergedMap.containsKey(entry.getKey())) {
                mergedMap.put(entry.getKey(), entry.getValue());
            }
        }

        ImageEx imageEx1=FoundLike(mergedMap);

//        // 输出分类后的信息
//        companyInfoMap.forEach(
//                (k, v) -> System.out.println("1**" + k + ": " + v)
//        );
//        mapadd.forEach(
//                (k, v) -> System.out.println("2**" + k + ": " + v)
//        );
//        mergedMap.forEach(
//                (k, v) -> System.out.println("3**" + k + ": " + v)
//        );
        return Result.success(imageEx1);
    }

    public static class ImageRequestObject {
        private String imageUrl;

        // 添加getter和setter方法
        public String getImageUrl() {
            return imageUrl;
        }

        public void setImageUrl(String imageUrl) {
            this.imageUrl = imageUrl;
        }
    }

    public class QiniuImageLoader {

        private final OkHttpClient client = new OkHttpClient();

        public BufferedImage loadImageFromQiniu(String imageUrl) throws IOException {
            Request request = new Request.Builder()
                    .url(imageUrl)
                    .build();

            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("Failed to load image from URL: " + imageUrl);
                }

                // 将响应体转换为字节数组
                byte[] imageData = response.body().bytes();

                // 使用ByteArrayInputStream将字节数组转换为InputStream
                InputStream in = new ByteArrayInputStream(imageData);

                // 使用ImageIO读取图像
                BufferedImage image = ImageIO.read(in);
                return image;
            }
        }
    }
    private ImageEx FoundLike(Map<String,String> map){
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value=entry.getValue();
            if (key.contains("企业名称")) { // 检查key是否包含"企业名称"
                // 执行某些操作...
                imageEx.setFname(value);
            }
            if (key.contains("地址")) {
                imageEx.setAdress(value);
            }
            if (key.contains("法定代表人")) {
                imageEx.setLperson(value);
            }
            if (key.contains("资质")) {
                // 将value以分号分割转为字符串数组
                //String[] valuesArray = entry.getValue().split(";");
                // 将字符串数组转换为列表
                //List<String> valueList = Arrays.asList(valuesArray);
                //imageEx.setQnames(value);
            }
            if (key.contains("有效期")) {
                imageEx.setDate(value);
            }
            if (key.contains("证书编号")) {
                imageEx.setNumber(value);
            }
            if (key.contains("经济性质")) {
                imageEx.setFtype(value);
            }
       }

//        System.out.println("对象赋值为："
//                +" 法人："+imageEx.getLperson()
//                +" 有效期："+imageEx.getDate()
//                +" 企业名称："+imageEx.getFname()
//                +" 注册地址："+imageEx.getAdress()
//                +" 经济性质："+imageEx.getFtype()
//                +" 证书编号："+imageEx.getNumber());
        return imageEx;
    }

    // 新增方法，处理包含预定义关键字的行
    private Map<String, String> processLinesWithPredefinedKeys(Map<String, String> tempInfoMap) {
        List<String> predefinedKeys = Arrays.asList("企业名称", "地址","法人","代码","证书编号","有效期","经济性质"); // 添加更多预定义关键字

        Map<String, String> companyInfoMap = new HashMap<>();
        for (String line : tempInfoMap.values()) { // 改变循环结构，遍历values而不是keys
            for (String predefinedKey : predefinedKeys) {
                if (line.contains(predefinedKey + ":")) {
                    int index = line.indexOf(predefinedKey + ":");
                    int valueStartIndex = index + predefinedKey.length() + 1;
                    String value = line.substring(valueStartIndex).trim();
                    companyInfoMap.put(predefinedKey, value);
                    break;
                }
            }
        }

        return companyInfoMap;
    }
}